Popular Searches
Popular Course Categories
Popular Courses

Working with Constants Using the final Keyword

Working with Constants Using the final Keyword

Java Syntax, Variables, and Data Types

Working with Constants Using the final Keyword

Course: Core Java Training

Topic: Working with Constants Using the final Keyword

Course Link: Core Java Training Course

Demo Link: Register for a Course Demo

JustAcademy Website: Visit JustAcademy


1. Introduction to Constants in Java

In Java programming, constants are values that should not be reassigned after they have been established. Examples include the number of minutes in an hour, a fixed tax rate used by an application, a maximum number of login attempts, and mathematical values such as pi.

Java provides the final keyword to prevent a variable from being assigned more than once. When a variable represents a value that should remain fixed, declaring it as final communicates that intention and helps prevent accidental reassignment.

For example, an application may use a constant to represent the maximum number of products allowed in a shopping cart.

final int MAX_CART_ITEMS = 50;

System.out.println(MAX_CART_ITEMS);

In this example, MAX_CART_ITEMS is initialized to 50. After initialization, Java does not allow the variable to be assigned another value.

2. Learning Objectives

After completing this topic, you should be able to:

  • Understand the purpose of constants in Java.
  • Explain the role of the final keyword.
  • Declare and initialize final variables correctly.
  • Understand local, instance, and static final variables.
  • Use static final to define shared class constants.
  • Understand blank final variables and constructor initialization.
  • Distinguish final references from immutable objects.
  • Identify common errors involving final variables.
  • Apply constants in practical Java programs.

3. What Is the final Keyword?

The final keyword is a Java modifier that restricts certain kinds of changes. Its effect depends on whether it is applied to a variable, method, or class.

Usage Purpose Example
Final variable Prevents reassignment after the variable has been initialized. final int AGE = 25;
Final method Prevents a subclass from overriding the method. final void display()
Final class Prevents the class from being extended. final class Utility

This topic focuses primarily on constants and final variables. Final methods and classes are introduced here to explain the broader purpose of the keyword.

4. What Is a Constant?

A constant is a value that a program treats as fixed rather than changing throughout execution. Instead of repeating a literal value throughout the code, a developer can give it a meaningful name.

Example Without a Named Constant

double price = 2000.0;
double tax = price * 0.18;

System.out.println("Tax: " + tax);

The value 0.18 represents a rate, but its meaning is not immediately clear to every reader.

Example Using a Named Constant

final double TAX_RATE = 0.18;

double price = 2000.0;
double tax = price * TAX_RATE;

System.out.println("Tax: " + tax);

The name TAX_RATE communicates the purpose of the value. If the variable is accidentally reassigned later, the compiler reports an error.

Important distinction: In Java terminology, a constant variable specifically means a final variable of primitive type or type String initialized with a constant expression. In everyday programming, developers also commonly call other fixed static final fields constants.

5. Declaring and Initializing Final Variables

To declare a final variable, place the final keyword before its type.

Syntax

final dataType VARIABLE_NAME = value;

Examples

final int MAX_USERS = 100;
final double PI_VALUE = 3.14159;
final char GRADE = 'A';
final boolean IS_ACTIVE = true;
final String COUNTRY = "India";

Once these variables have been assigned their values, they cannot be reassigned.

Attempting to Reassign a Final Variable

final int MAX_USERS = 100;

MAX_USERS = 200; // Compilation error

The assignment fails because MAX_USERS is already initialized and declared as final.

Why Does Java Enforce This Rule?

  • It prevents accidental changes to values intended to remain fixed.
  • It makes the developer's intention clear to other programmers.
  • It improves code readability and maintainability.
  • It helps catch certain programming mistakes during compilation.
  • It makes shared configuration values easier to identify and reuse.

6. Naming Conventions for Constants

Java naming conventions commonly use uppercase letters with underscores between words for constants. This style is known as UPPER_SNAKE_CASE.

Purpose Recommended Name Example Declaration
Maximum login attempts MAX_LOGIN_ATTEMPTS static final int MAX_LOGIN_ATTEMPTS = 5;
Application name APPLICATION_NAME static final String APPLICATION_NAME = "ShopApp";
Timeout in seconds REQUEST_TIMEOUT_SECONDS static final int REQUEST_TIMEOUT_SECONDS = 30;
Conversion factor KILOMETERS_TO_METERS static final int KILOMETERS_TO_METERS = 1000;

Uppercase naming is a convention, not a requirement imposed by the compiler. A final local variable can also use camelCase if that is more appropriate to its context.

Good and Poor Naming Examples

// Less descriptive
final int X = 5;
final double N = 0.18;

// More descriptive
final int MAX_RETRY_COUNT = 5;
final double TAX_RATE = 0.18;

Meaningful names make it easier to understand what a value represents without searching through the entire program.

7. Understanding static final Constants

The combination of static and final is commonly used for class-level constants.

  • static means the field belongs to the class rather than to each individual object.
  • final means the field cannot be reassigned after initialization.

Syntax

static final dataType CONSTANT_NAME = value;

Example

class MathConstants {
    static final double PI = 3.141592653589793;
    static final int DAYS_IN_WEEK = 7;
    static final int HOURS_IN_DAY = 24;
}

public class Main {
    public static void main(String[] args) {
        System.out.println(MathConstants.PI);
        System.out.println(MathConstants.DAYS_IN_WEEK);
        System.out.println(MathConstants.HOURS_IN_DAY);
    }
}

Output

3.141592653589793
7
24

The constants are accessed through the class name, such as MathConstants.PI. Because the fields are static, creating a MathConstants object is unnecessary to access them.

Why Use static final Together?

  • One class-level field can represent a value shared by all objects.
  • It avoids creating a separate field for every object when a shared constant is appropriate.
  • It clearly distinguishes class-wide fixed values from instance-specific state.
  • It supports centralized definitions for commonly used values.

8. Types of Final Variables

Final variables can be declared in different locations depending on their intended use.

Type Location Example Purpose
Local final variable Inside a method or block final int count = 10; Prevents reassignment within that local scope.
Instance final field Inside a class, outside methods, without static final int employeeId; Allows each object to receive its own fixed value.
Static final field Inside a class with static static final int MAX_SIZE = 100; Represents a shared class-level constant.
Final parameter Inside a method or constructor parameter list void print(final int value) Prevents reassignment of the parameter within the method.

9. Local Final Variables

A local final variable is declared inside a method, constructor, or block. It can be initialized at the time of declaration or assigned later, provided it is assigned exactly once before use and all execution paths satisfy Java's definite-assignment rules.

Example: Initialization at Declaration

public class LocalConstantExample {
    public static void main(String[] args) {
        final int BONUS_POINTS = 10;
        int score = 80;

        int finalScore = score + BONUS_POINTS;

        System.out.println(finalScore);
    }
}

Output

90

Example: Assignment Later

public class BlankLocalFinal {
    public static void main(String[] args) {
        final int MAX_SCORE;

        MAX_SCORE = 100;

        System.out.println(MAX_SCORE);
    }
}

This is valid because MAX_SCORE is assigned once before it is used. The variable cannot be assigned again after that.

10. Instance Final Variables

An instance final variable is a field that belongs to an individual object. Each object can have its own value, but that field cannot be reassigned after initialization.

Example

class Employee {
    final int employeeId;
    String employeeName;

    Employee(int employeeId, String employeeName) {
        this.employeeId = employeeId;
        this.employeeName = employeeName;
    }

    void display() {
        System.out.println("ID: " + employeeId);
        System.out.println("Name: " + employeeName);
    }
}

public class Main {
    public static void main(String[] args) {
        Employee first = new Employee(101, "Aarav");
        Employee second = new Employee(102, "Riya");

        first.display();
        second.display();
    }
}

Output

ID: 101
Name: Aarav
ID: 102
Name: Riya

Each employee receives a different employeeId during construction. After construction, the field cannot be reassigned. The employeeName field is not final, so it can be changed if required.

11. Static Final Variables

A static final variable is commonly used when a fixed value should be shared across all instances of a class.

Example: Application Configuration

class AppConfig {
    static final String APP_NAME = "StudentPortal";
    static final int MAX_LOGIN_ATTEMPTS = 3;
    static final int SESSION_TIMEOUT_MINUTES = 20;
}

public class Main {
    public static void main(String[] args) {
        System.out.println(AppConfig.APP_NAME);
        System.out.println(AppConfig.MAX_LOGIN_ATTEMPTS);
        System.out.println(AppConfig.SESSION_TIMEOUT_MINUTES);
    }
}

Output

StudentPortal
3
20

This approach is useful when the same fixed value is required in multiple parts of a program. Instead of repeating the same literal, code can refer to the named constant.

12. Blank Final Variables

A blank final variable is a final variable declared without an initializer. Java requires it to be assigned exactly once before it is used and, for a field, before the relevant constructor or class initialization completes.

Blank Final Instance Field

class Rectangle {
    final int width;
    final int height;

    Rectangle(int width, int height) {
        this.width = width;
        this.height = height;
    }

    int calculateArea() {
        return width * height;
    }
}

public class Main {
    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle(10, 5);
        System.out.println(rectangle.calculateArea());
    }
}

Output

50

The constructor initializes both final fields. Different rectangle objects may have different dimensions, but each object's dimensions cannot be reassigned after initialization.

Blank Final Static Field

A static final field can also be initialized inside a static initializer block when its value cannot conveniently be placed directly in the declaration.

class SystemSettings {
    static final String MODE;

    static {
        MODE = "PRODUCTION";
    }
}

The static initializer runs when the class is initialized. The field must receive its value before class initialization completes.

13. Final Variables and Reference Types

A frequent misunderstanding is that declaring an object reference as final makes the entire object immutable. This is not correct.

When a reference variable is final, the reference cannot be changed to point to another object after assignment. However, the referenced object may still be mutable.

Example with a Final Reference

class Student {
    String name;

    Student(String name) {
        this.name = name;
    }
}

public class Main {
    public static void main(String[] args) {
        final Student student = new Student("Aarav");

        student.name = "Riya";

        System.out.println(student.name);

        // Not allowed:
        // student = new Student("Kabir");
    }
}

Output

Riya

The statement student.name = "Riya"; is allowed because it changes the object's field, not the reference stored in student. Assigning a different object to student is not allowed.

Final Arrays

final int[] numbers = {10, 20, 30};

numbers[0] = 99; // Allowed

// Not allowed:
// numbers = new int[] {1, 2, 3};

System.out.println(numbers[0]);

Output

99

The array's elements can change, but the final reference cannot be reassigned. If you need an object whose state cannot change, use an immutable class or design the class so that mutable state is not exposed.

14. The Difference Between final, finally, and finalize

These three terms look similar but serve different purposes in Java.

Term Meaning Example
final Keyword used with variables, methods, and classes to restrict reassignment, overriding, or inheritance. final int LIMIT = 10;
finally Block associated with exception handling that normally executes when control leaves a try statement, subject to abrupt termination and other runtime conditions. try { } finally { }
finalize() An old Object method associated with finalization. It is deprecated for removal and should not be relied on for resource cleanup. Avoid using it in new code.

For releasing files, database connections, and other resources, prefer try-with-resources and explicit resource management rather than relying on finalize().

15. Constants in Real-World Java Applications

Constants are useful in many kinds of applications. They help centralize fixed values and communicate their purpose.

15.1 E-Commerce Applications

class ShoppingCartConfig {
    static final int MAX_CART_ITEMS = 50;
    static final int FREE_SHIPPING_MINIMUM = 1000;
}

These constants can represent application limits and a configured shipping threshold. In a real system, business rules that change frequently may belong in external configuration or a database rather than being compiled into the application.

15.2 Banking Applications

class BankingConfig {
    static final int MAX_PIN_ATTEMPTS = 3;
    static final int TRANSACTION_TIMEOUT_SECONDS = 30;
}

Named constants can make fixed technical limits clear. Security-sensitive and operational rules should still be reviewed carefully and configured appropriately for the production environment.

15.3 Education Applications

class ExamSettings {
    static final int PASSING_MARKS = 40;
    static final int MAX_MARKS = 100;
}

These constants help avoid repeated numeric literals when displaying or validating exam results.

15.4 Unit Conversion

class UnitConverter {
    static final int METERS_PER_KILOMETER = 1000;

    static double toMeters(double kilometers) {
        return kilometers * METERS_PER_KILOMETER;
    }
}

16. Complete Practical Program Using Constants

The following example uses constants to calculate the area of a circle and display its circumference.

class CircleCalculator {
    static final double PI = 3.141592653589793;

    static double calculateArea(double radius) {
        return PI * radius * radius;
    }

    static double calculateCircumference(double radius) {
        return 2 * PI * radius;
    }
}

public class Main {
    public static void main(String[] args) {
        final double radius = 5.0;

        double area = CircleCalculator.calculateArea(radius);
        double circumference =
                CircleCalculator.calculateCircumference(radius);

        System.out.println("Radius: " + radius);
        System.out.println("Area: " + area);
        System.out.println("Circumference: " + circumference);
    }
}

Output

Radius: 5.0
Area: 78.53981633974483
Circumference: 31.41592653589793

Program Explanation

  • PI is a static final field shared by the class.
  • radius is a local final variable that cannot be reassigned.
  • calculateArea() calculates the circle's area.
  • calculateCircumference() calculates the circle's circumference.
  • The program avoids repeating the value of pi in multiple formulas.

17. Common Errors When Using final

Error 1: Reassigning a Final Variable

final int MAX_USERS = 100;
MAX_USERS = 150; // Compilation error

Solution: Do not reassign a final variable. If the value must change during execution, use a non-final variable instead.

Error 2: Using a Blank Final Field Without Initializing It

class Product {
    final int productId;

    Product() {
        // productId is not initialized
    }
}

Problem: The constructor does not assign a value to the blank final instance field.

Solution: Initialize the field at its declaration or assign it in every constructor that must initialize it.

class Product {
    final int productId;

    Product(int productId) {
        this.productId = productId;
    }
}

Error 3: Assuming a Final Object Is Immutable

final StringBuilder message = new StringBuilder("Hello");

message.append(" Java"); // Allowed

// message = new StringBuilder("New"); // Compilation error

Solution: Remember that final restricts reassignment of the reference. It does not automatically make the referenced object immutable.

Error 4: Trying to Initialize a Static Final Field in an Instance Constructor

class Configuration {
    static final int PORT;

    Configuration() {
        // PORT = 8080; // Not a valid initialization location
    }
}

Solution: Initialize a static final field at its declaration or in a static initializer block.

class Configuration {
    static final int PORT = 8080;
}

Error 5: Declaring a Constant with a Vague Name

static final int VALUE = 60;

Solution: Use a name that explains the value's meaning, such as SECONDS_PER_MINUTE.

18. Best Practices for Working with Constants

  • Use final when a variable should not be reassigned after initialization.
  • Use static final for values shared by the class and intended to remain fixed.
  • Follow the UPPER_SNAKE_CASE convention for class constants.
  • Choose descriptive names instead of unexplained numeric or string literals.
  • Keep constants close to the class or module that owns their meaning.
  • Avoid creating a single miscellaneous constants class containing unrelated values from the entire application.
  • Do not assume that a final reference makes an object immutable.
  • Use constructors to initialize instance final fields when each object requires its own fixed value.
  • Use static initializer blocks only when static final fields cannot be initialized conveniently at the declaration.
  • Keep environment-specific settings, secrets, and frequently changing business rules outside compiled constants when appropriate.
  • Do not use final automatically on every variable; use it where it improves correctness or communicates intent.

19. Practical Exercises

Exercise 1: Declare Basic Constants

Create final variables for the following values:

  • Maximum number of students: 60
  • Days in a week: 7
  • Application name: LearningPortal
  • Conversion factor from kilometers to meters: 1000

Print all four values to the console.

Exercise 2: Fix the Compilation Error

public class Main {
    public static void main(String[] args) {
        final double PI = 3.14159;
        PI = 3.14;
        System.out.println(PI);
    }
}

Identify why the program fails and rewrite it so that it compiles.

Exercise 3: Create an Employee Class

Create an Employee class with a final employee ID and a changeable employee name. Initialize the employee ID through the constructor and write a method to display both fields.

Exercise 4: Build a Unit Converter

Create a class with a static final conversion constant for centimeters per meter. Write a method that converts meters to centimeters and test it with multiple values.

Exercise 5: Understand Final References

Declare a final array containing three numbers. Change one array element and print the array. Then explain why assigning a new array to the same final variable is not allowed.

20. Interview Questions and Answers

Q1. What is the purpose of the final keyword in Java?

Answer: The final keyword restricts reassignment of variables, overriding of methods, and inheritance from classes, depending on how it is used.

Q2. How do you declare a constant in Java?

Answer: Use the final keyword for a variable that should not be reassigned. A common class-level constant declaration is static final int MAX_SIZE = 100;.

Q3. What is the difference between final and static final?

Answer: final prevents reassignment. static final also makes the field belong to the class rather than to each individual instance.

Q4. Can a final variable be initialized later?

Answer: Yes. A blank final variable may be initialized later, provided it is assigned exactly once and Java's definite-assignment rules are satisfied.

Q5. Can a final instance variable have different values in different objects?

Answer: Yes. A final instance field can be initialized separately in each object's constructor. Its value cannot be reassigned after initialization.

Q6. Can a final reference point to another object later?

Answer: No. Once assigned, a final reference cannot be reassigned to another object.

Q7. Can the contents of a final array be changed?

Answer: Yes. A final array reference cannot be reassigned, but its elements can be modified unless other restrictions apply.

Q8. Why are constants commonly written in uppercase?

Answer: Uppercase letters with underscores are a naming convention that makes constants easy to recognize. It is a convention rather than a compiler requirement.

Q9. Where can a static final field be initialized?

Answer: It can be initialized in its declaration or in a static initializer block.

Q10. What is a blank final variable?

Answer: A blank final variable is declared without an initial value and must be assigned exactly once before it is used and before its required initialization point is completed.

Q11. Is every final variable a compile-time constant?

Answer: No. A Java constant variable, in the language specification's precise sense, must be final, have primitive or String type, and be initialized with a constant expression. Other final variables may hold objects or values determined at runtime.

Q12. What is the difference between final and immutable?

Answer: Final prevents reassignment of a variable or reference. Immutability means an object's observable state cannot change after creation. A final reference may still point to a mutable object.

21. Quick Revision Checklist

  • The final keyword restricts reassignment of variables.
  • A final variable must be assigned before use and cannot be reassigned after initialization.
  • static final is commonly used for class-level constants.
  • Constants conventionally use uppercase names separated by underscores.
  • Blank final fields can be initialized through constructors or initializer blocks as appropriate.
  • Instance final fields can have different values in different objects.
  • Static final fields represent shared class-level values.
  • A final object reference cannot be reassigned, but the referenced object may still be mutable.
  • Meaningful constant names make programs easier to understand.
  • Final methods cannot be overridden, and final classes cannot be extended.

22. Conclusion

The final keyword is an important feature of Core Java. It allows developers to prevent unwanted variable reassignment, define class-level constants, and communicate which values are intended to remain fixed. Using final variables appropriately improves code clarity, reduces certain programming errors, and makes program behavior easier to reason about.

As you continue learning Java, practice creating local final variables, instance final fields, and static final constants. Pay special attention to the difference between a final reference and an immutable object, because this distinction is important when working with arrays and other reference types.

To continue learning, explore the Core Java Training Course, register through the JustAcademy course demo page, or visit the JustAcademy website.

whatsapp